package cc.verywell.pureblock.msg.nfs.linkmap;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import cc.verywell.pureblock.util.AutoClosed;

/**
* 
* Copyright © 2019 TanYaqiu. All rights reserved.
* @author TanYaqiu 
* @address flat 601
* @date 2019年6月19日 下午4:51:11
*/
public class EasyCompactMemToHd implements EasyCompact {

	final private EasyTableMem mem;
	final private AtomicBoolean mutex = new AtomicBoolean(false);
	public EasyCompactMemToHd(EasyTableMem mem) {
		this.mem = mem;
	}

	@Override
	public void compact(EasyFileController efc, EasyCompactFinish cf) {
		if(mutex.getAndSet(true))throw new EasyIOException("compact already running!");
		
		EasyIterator it = mem.get(LinkCell.MIN);
		ArrayList<EasyTableHDhead> gen = new ArrayList<>();
		while(it.hasNext()) {
			
			if(Thread.currentThread().isInterrupted())throw new EasyIOException("Interrupted");
			
			long newFileNumber = efc.getNewFileNumber();
			Path newFilePath = efc.getHDfile(newFileNumber);
			EasyTableHDhead head = EasyTableHD.add(0, newFileNumber, newFilePath, it, SIZELIMIT);
			gen.add(head);
		}
		
		synchronized (cf.sync()) {
			EasyTableGroup old = cf.syncGetGroup();
			ArrayList<EasyTableHDhead> newUnsort = new ArrayList<>(old.getUnsort().files.size()+gen.size());
			newUnsort.addAll(old.getUnsort().files);
			newUnsort.addAll(gen);
			Collections.sort(newUnsort);
			EasyTableGroup ng = new EasyTableGroup(new EasyTablesUnsort(efc.getAC(), newUnsort), old.getSorteds());
			
			cf.syncLog().writetedMemToHd(mem.fileNumber, gen, efc.logGetFileNumber(), efc.logGetSeq());
			cf.syncSetGroup(ng);
		}
		
		mem.delete();
		
		cf.doLast();
	}


	final static public EasyCompactSizeLimit SIZELIMIT = new EasyCompactSizeLimit() {
		@Override
		public void newFile() {}
		@Override
		public boolean sizeLimit(long pos) {
			return pos > EasyFileController.GRADE_EXPANDED;
		}
	};
	

}
